package com.hc.java.fiber;

import co.paralleluniverse.fibers.Fiber;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;

/**
 * 协程池
 *
 * @author huangchao E-mail:fengquan8866@163.com
 * @version 创建时间：2024/6/20 22:18
 */
@Slf4j
public class FiberWorkPool {

    /**
     * 工作协程数组
     */
    private List<Fiber> workThreads;

    /**
     * 协程任务倒计数门栓
     */
    @Getter
    private CountDownLatch countDownLatch = new CountDownLatch(0);

    /**
     * 建立协程池，taskCount 为协程池中工作协程的个数
     * @param taskCount
     */
    public FiberWorkPool(int taskCount) {
        this.workThreads = new ArrayList<>(taskCount);
        countDownLatch = new CountDownLatch(taskCount);
    }

    /**
     * 任务加入任务队列
     */
    public void execute(Fiber task) {
        try {
            workThreads.add(task); // 阻塞接口的Fiber work插入
        } catch (Exception e) {
            log.error("--Fiber work add failed ..., msg: {}", e.getMessage());
        }
    }

    // 销毁协程池，该方法保证全部任务都完成的状况下才销毁全部协程，不然等待认为完成再销毁
    public void shutdown() throws InterruptedException {
        start();
        countDownLatch.await();
        workThreads.clear(); // 清空等待队列
        log.debug("-- successfully closed FiberWorkPool ...");
    }

    /**
     * 启动协程池里所有的协程
     */
    private void start() {
        if (workThreads.size() != 0) {
            for (Fiber fiber : workThreads) {
                fiber.start();
            }
        }
    }
}
